package com.audaque.springboot.foshanupload.security.valid.provider;

import com.audaque.springboot.foshanupload.security.encoder.MyPasswordEncoder;
import com.audaque.springboot.foshanupload.security.model.MyUserDetail;
import com.audaque.springboot.foshanupload.security.service.impl.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
public class UserVerifyAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private MyPasswordEncoder myPasswordEncoder;
    @Autowired
    private MyUserDetailService myUserDetailService;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String userName = (String) authentication.getPrincipal(); // Principal 主体，一般指用户名
        String passWord = (String) authentication.getCredentials(); //Credentials 网络凭证,一般指密码
        //通过账号去数据库查询用户以及用户拥有的角色信息
        MyUserDetail myUserDetail = (MyUserDetail)myUserDetailService.loadUserByUsername(userName);
        if (myUserDetail==null) {
            throw new UsernameNotFoundException("用户名不存在！");
        }
        //数据库密码
        String encodedPassword = myUserDetail.getPassword();
        //credentials凭证即为前端传入密码，因为前端一般用Base64加密过所以需要解密。
        //String credPassword = new String(Base64Utils.decodeFromString(passWord), StandardCharsets.UTF_8);
        // 验证密码：前端明文，数据库密文
        if (!myPasswordEncoder.matches(passWord, encodedPassword)) {
            throw new BadCredentialsException("密码错误！");
        }
        LocalDateTime passwordExpireTime = myUserDetail.getPasswordExpireTime();
        if (passwordExpireTime != null && LocalDateTime.now().isAfter(passwordExpireTime)) {
            throw new CredentialsExpiredException("密码已过期！");
        }
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userName, passWord, myUserDetail.getAuthorities());
        token.setDetails(myUserDetail);//这里可以放用户的详细信息
        return token;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return false;
    }
}